package main

import "fmt"

//https://gfw.go101.org/article/interface.html

//Go中的内置反射机制。
//在Go中，内置反射机制包括类型断言（type assertion）和type-switch流程控制代码块。

//如果我们不关心一个type-switch代码块中的断言结果，则此type-switch代码块可简写为switch x.(type) {...}。
//
//type-switch代码块和switch-case代码块有很多共同点：
//在一个type-switch代码块中，最多只能有一个default分支存在。
//在一个type-switch代码块中，如果default分支存在，它可以为最后一个分支、第一个分支或者中间的某个分支。
//一个type-switch代码块可以不包含任何分支，它可以被视为一个空操作。
//但是，和switch-case代码块不一样，fallthrough语句不能使用在type-switch代码块中
func main() {
	values := []interface{}{
		456, "abc", true, 0.33, int32(789),
		[]int{1, 2, 3}, map[int]bool{}, nil,
	}
	for _, x := range values {
		// 这里，虽然变量v只被声明了一次，但是它在
		// 不同分支中可以表现为多个类型的变量值。
		switch v := x.(type) {
		case []int: // 一个类型字面表示
			// 在此分支中，v的类型为[]int。
			fmt.Println("int slice:", v)
		case string: // 一个类型名
			// 在此分支中，v的类型为string。
			fmt.Println("string:", v)
		case int: // 多个类型名
			// 在此分支中，v的类型为x的类型interface{}。
			fmt.Println("int:", v)
		case int32:
			fmt.Println("int32:", v)
		case float64:
			fmt.Println("float64:", v)
		case nil:
			// 在此分支中，v的类型为x的类型interface{}。
			fmt.Println(v)
		default:
			// 在此分支中，v的类型为x的类型interface{}。
			fmt.Println("others:", v)
		}
		// 注意：在最后的三个分支中，v均为接口值x的一个复制。
	}
}
